package com.zivwu.library;


import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import com.tbruyelle.rxpermissions2.RxPermissions;
import com.zivwu.library.dao.bean.Photo;
import com.zivwu.library.ui.photo.PhotoPickerActivity;
import com.zivwu.library.ui.photo.PhotoPreviewActivity;
import com.zivwu.library.utils.ToastUtil;

import java.util.ArrayList;

import io.reactivex.functions.Consumer;

public class PhotoPicker {
    public static final int REQUEST_CODE = 233;


    public final static String KEY_SELECTED_PHOTOS = "SELECTED_PHOTOS";

    public static final String EXTRA_PHOTO_DATA = "PHOTO_DATA";
    public final static String EXTRA_MAX_COUNT = "MAX_COUNT";

    public final static String EXTRA_PREVIEW_PHOTO = "EXTRA_PREVIEW_PHOTO";
    public final static String EXTRA_PHOTO_INDEX = "EXTRA_PHOTO_INDEX";


    public static PhotoPickerBuilder builder() {
        return new PhotoPickerBuilder();
    }


    public static class PhotoPickerBuilder {
        private Bundle mPickerOptionsBundle;
        private Intent mPickerIntent;


        public PhotoPickerBuilder() {
            mPickerOptionsBundle = new Bundle();
            mPickerIntent = new Intent();
        }

        public void start(@NonNull Activity activity) {
            this.start(activity, REQUEST_CODE);
        }


        public void start(@NonNull final Activity activity, final int requestCode) {
            RxPermissions permissions = new RxPermissions(activity);
            permissions.request(Manifest.permission.CAMERA,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(new Consumer<Boolean>() {
                        @Override
                        public void accept(Boolean aBoolean) throws Exception {
                            if (aBoolean) {
                                onPermissionsHave(activity, requestCode);
                            } else {
                                ToastUtil.showToast(activity.getApplicationContext(),
                                        R.string.ziv_permission_error_photo_picker);
                            }
                        }
                    });

        }

        private void onPermissionsHave(@NonNull Activity activity, int requestCode) {
            if (isCrop()) {
                goCropPhoto(activity, requestCode, mPickerOptionsBundle, mPickerIntent);
            } else if (isPreView()) {
                goPreviewActivity(activity);
            } else {
                onWindowShow(activity, requestCode);
            }
        }

        private void goCropPhoto(@NonNull Activity activity, int requestCode, Bundle mPickerOptionsBundle, Intent mPickerIntent) {
            mPickerOptionsBundle.putBoolean("crop", true);
            mPickerOptionsBundle.putBoolean("scale", true);//保持碧绿
            mPickerOptionsBundle.putBoolean("noFaceDetection", true); // 头像识别
            mPickerOptionsBundle.putString("outputFormat", Bitmap.CompressFormat.JPEG.toString());
            mPickerIntent.putExtras(mPickerOptionsBundle);
            activity.startActivityForResult(mPickerIntent, RequestCode.makeRequestCode(requestCode, RequestCode.CROP));
        }

        private boolean isPreView() {
            ArrayList<Parcelable> list = mPickerOptionsBundle.getParcelableArrayList(EXTRA_PREVIEW_PHOTO);
            return list != null && list.size() > 0;
        }

        private boolean isCrop() {
            return mPickerIntent.getData() != null;
        }

        private void onWindowShow(@NonNull final Activity activity, final int requestCode) {
            final ChoseItemWindow window = new ChoseItemWindow(activity);
            window.show();
            window.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    goPickPhoto(activity,
                            RequestCode.makeRequestCode(requestCode, RequestCode.CAMERA));
                    window.dismiss();
                }
            }, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    goPickPhoto(activity,
                            RequestCode.makeRequestCode(requestCode, RequestCode.ALBUM));
                    window.dismiss();
                }
            }, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    window.dismiss();
                }
            });


        }


        private void goPickPhoto(Activity activity, int requestCode) {
            mPickerIntent.putExtras(mPickerOptionsBundle);
            if (RequestCode.getMode(requestCode) == RequestCode.ALBUM) {
                mPickerIntent.setClass(activity, PhotoPickerActivity.class);
                activity.startActivityForResult(mPickerIntent, requestCode);
            } else {
                mPickerIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
                if (mPickerIntent.resolveActivity(activity.getPackageManager()) != null) {
                    activity.startActivityForResult(mPickerIntent, requestCode);
                }

            }

        }


        private void goPreviewActivity(Activity activity) {
            mPickerIntent.setClass(activity, PhotoPreviewActivity.class);
            mPickerIntent.putExtras(mPickerOptionsBundle);
            activity.startActivity(mPickerIntent);
            // TODO: 2017/9/21 0021 activity Transition
            activity.overridePendingTransition(R.anim.ziv_activity_enter, R.anim.ziv_activity_exit);
        }


        public PhotoPickerBuilder setPhotoCount(int photoCount) {
            mPickerOptionsBundle.putInt(EXTRA_MAX_COUNT, photoCount);
            return this;
        }


        public PhotoPickerBuilder setPreviewPhoto(ArrayList<Photo> photoArrayList) {
            mPickerOptionsBundle.putParcelableArrayList(EXTRA_PREVIEW_PHOTO, photoArrayList);
            return this;
        }

        public PhotoPickerBuilder setPhotoIndex(int index) {
            mPickerOptionsBundle.putInt(EXTRA_PHOTO_INDEX, index);
            return this;
        }


        public PhotoPickerBuilder setExtraOutput(Uri uri) {
            mPickerOptionsBundle.putParcelable(MediaStore.EXTRA_OUTPUT, uri);
            return this;
        }


        public Bundle getBundle() {
            return mPickerOptionsBundle;
        }


        public PhotoPickerBuilder setDataAndType(Uri inUri) {
            mPickerIntent.setAction("com.android.camera.action.CROP");
            mPickerIntent.setDataAndType(inUri, "image/*");
            return this;
        }

    }


    public static class RequestCode {
        private static final int MODE_SHIFT = 29;
        private static final int MODE_MASK = 0x3 << MODE_SHIFT;


        public static final int CAMERA = 0 << MODE_SHIFT;
        public static final int ALBUM = 1 << MODE_SHIFT;
        public static final int CROP = 2 << MODE_SHIFT;


        public static int makeRequestCode(@IntRange(from = 0, to = (1 << RequestCode.MODE_SHIFT) - 1) int requestCode, int mode) {
            return requestCode + mode;
        }


        public static int getMode(int measureSpec) {
            return (measureSpec & MODE_MASK);
        }

        public static int getCode(int measureSpec) {
            return (measureSpec & ~MODE_MASK);
        }


    }


    private static class ChoseItemWindow extends android.widget.PopupWindow {
        private Activity activity;
        private ViewGroup rootView;

        public ChoseItemWindow(Activity activity) {
            this.activity = activity;
            init();
        }

        private void init() {
            rootView = getRootView(R.layout.ziv_poup_photo_picker_select);
            setContentView(rootView);
            setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
            setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            this.setFocusable(true);
            this.setBackgroundDrawable(new ColorDrawable());
            this.setAnimationStyle(R.style.BottomPopupAnim);
            this.setOnDismissListener(new OnDismissListener() {
                @Override
                public void onDismiss() {
                    setActivityGray(1.0f);
                }
            });
        }


        public void show() {
            showAtLocation(activity.getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
            setActivityGray(0.5f);
        }

        private void setActivityGray(float alpha) {
            WindowManager.LayoutParams params = activity.getWindow().getAttributes();
            params.alpha = alpha;
            activity.getWindow().setAttributes(params);
        }


        private ViewGroup getRootView(int res) {
            return (ViewGroup) LayoutInflater.from(activity)
                    .inflate(res,
                            (ViewGroup) activity.getWindow().getDecorView(),
                            false);

        }


        public void setOnClickListener(View.OnClickListener... listener) {
            if (listener == null || listener.length == 0)
                return;

            for (int i = 0; i < listener.length; i++) {
                rootView.getChildAt(i).setOnClickListener(listener[i]);
            }

        }
    }

}
